home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / WAIS / next-ui / Wais.h < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-03  |  12.8 KB  |  371 lines

  1. //
  2. //        WAIS PROTOCOL OBJECTIVE-C INTERFACE
  3. //            main header file Wais.h
  4. //
  5. // Free software created 1 Feb 1992
  6. // by Paul Burchard <burchard@math.utah.edu>.
  7. //
  8. // This software is distributed at no cost, with no restrictions, and with
  9. // no guarantees.  But it works pretty damn good anyway... :-)
  10. //
  11.  
  12. // Incorporating:
  13. /* 
  14.    WIDE AREA INFORMATION SERVER SOFTWARE:
  15.    No guarantees or restrictions.  See the readme file for the full standard
  16.    disclaimer.
  17.  
  18.    This is part of the [NeXTstep] user-interface for the WAIS software.
  19.    Do with it as you please.
  20.  
  21.    Version 0.82
  22.    Wed Apr 24 1991
  23.  
  24.    jonathan@Think.COM
  25.  
  26. */
  27.  
  28. // Original warranty disclaimer:
  29. /*
  30. ------------------------------------------------------------------------
  31.  
  32. WARRANTY DISCLAIMER
  33.  
  34. This software was created by Thinking Machines Corporation and is distributed 
  35. free of charge.  It is placed in the public domain and permission is granted 
  36. for anyone to use, duplicate, modify and redistribute it.
  37.  
  38. Thinking Machines Corporation provides absolutely NO WARRANTY OF ANY KIND with
  39. respect to this software.  The entire risk as to the quality and performance 
  40. of this software is with the user.  IN NO EVENT WILL THINKING MACHINES 
  41. CORPORATION BE LIABLE TO ANYONE FOR ANY DAMAGES ARISING OUT THE USE OF THIS
  42. SOFTWARE, INCLUDING, WITHOUT LIMITATION, DAMAGES RESULTING FROM LOST DATA OR
  43. LOST PROFITS, OR FOR ANY SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES.
  44.  
  45. ------------------------------------------------------------------------
  46. */
  47.  
  48.  
  49.  
  50. //---------------------------------------------------------------------------
  51. //
  52. //            ABOUT THE WAIS CLASSES.
  53. //
  54. // (The class declarations are near the end of this file.)
  55. //
  56. // Our object wrapper for WAIS has three classes: WaisQuestion, WaisSource,
  57. // and WaisDocument.  Documents are retrieved from sources.  Questions produce 
  58. // a list of documents and relevance scores, when given a string of keywords to 
  59. // match, a list of sources to search, and a list of relevant documents to 
  60. // emulate.  Scores are numbers in the range from 0.0 to 1.0, with 1.0 denoting 
  61. // the best-matching document found.
  62. //
  63. // To facilitate user manipulation of sources and documents, which can be 
  64. // shared among several questions, WAIS objects can be accessed by string keys
  65. // (via +objectForKey:).  The string key is the full path of the file in which 
  66. // the object is stored---or would be stored upon retrieval.  WAIS objects will 
  67. // be automatically loaded from their WAIS structured files as necessary when
  68. // a key lookup is performed.  Note that keys are actually NXAtoms.
  69. //
  70. // To support lookup with incomplete keys and creation of objects from 
  71. // incomplete keys, each class also has a folder list (a Storage object of 
  72. // NXAtoms) which is used as a search path.  (For creation, the first element 
  73. // of the folder list is used).  The folder list is set by the subclasses (see 
  74. // the "Folder" methods below) and initially contains an appropriate subfolder 
  75. // of "~/Library/WAIS/".
  76. //
  77. // All WAIS objects contain lists of information fields, which are stored via 
  78. // associative tables connecting field names to values.  These info fields
  79. // encode most of the parameters of the WAIS objects.  These info fields, along 
  80. // with any other necessary data, are read from and written to WAIS structured 
  81. // files [see below] with the -readWaisFile and -writeWaisFile methods (which 
  82. // use the key as the file name).
  83. //
  84. // If so enabled during compilation [see below], these classes provide support 
  85. // for running WAIS procedures (typically, retrievals and searches) in separate 
  86. // MACH threads.  The support has two parts: the first is a set of mutex 
  87. // locking methods, which are also used here internally.  The second is a 
  88. // callback method that allows you to send thread-unsafe object messages (such 
  89. // as those involving the AppKit) back to the main thread for execution.
  90. //
  91. // Aside from setting up callbacks (if so enabled), these classes use the 
  92. // NeXTstep AppKit only to put up Alert Panels; and even this is only enabled 
  93. // if an NXStringTable of error messages has been established via the class 
  94. // method +setStringTable:.
  95. //
  96. // The NXStringTable of error messages is shared among the current classes,
  97. // so a call to [Wais setStringTable:...] is enough.  The following string keys 
  98. // are needed if Alert Panels are desired:
  99. //
  100. //    "OK"
  101. //    "WAIS Question Error!"
  102. //    "WAIS Source Error!"
  103. //    "WAIS Document Error!"
  104. //    "Can't connect to server %s."
  105. //    "Can't open folder %s."
  106. //    "Can't connect to source %s."
  107. //    "No sources to search."
  108. //    "Bad source %s."
  109. //    "Unknown source %s."
  110. //    "No key words for search."
  111. //    "Buffer overflow: request too large for source %s."
  112. //    "Warning: no information returned from source %s."
  113. //    "Search diagnostics: %s, %s"
  114. //    "Source %s returned bad search response."
  115. //    "Can't form document for headline %s."
  116. //    "Found no documents matching the question."
  117. //    "Found no documents with positive matching scores."
  118. //    "Can't create local document file %s."
  119. //    "Document %s is empty."
  120. //    "Overflow: retrieval request too large for %s."
  121. //    "Warning: missing data for document %s."
  122. //    "Retrieval diagnostics: %s, %s"
  123. //    "Bad %s file format: %s."
  124. //    "Can't read %s file: %s."
  125. //    "Can't create %s file %s."
  126. //    "Error writing %s file %s."
  127. //    "Write error on document %s."
  128. //    "Retrieving document...press to abort"
  129. //    "Retrieving %d documents...press to abort"
  130. //    "Document specification garbled."
  131. //    "No Doc-ID for %s."
  132. //    "Bad document scores."
  133. //
  134.  
  135.  
  136. //-----------------------------------------------------------------------
  137. //
  138. //            Support for multiple MACH Threads.
  139. //
  140. // If you want support for threads, make sure WAIS_THREAD_SUPPORT is #defined.
  141. //
  142. // This sets up the WAIS classes with locking methods which can be used to help 
  143. // prevent conflicts between multiple threads of execution.  These methods are
  144. // no-ops if thread support is not enabled.  If your program uses threads and
  145. // contains potential conflicts with the operations below, you'll need to
  146. // frame those operations with the corresponding pair of Wais class locking
  147. // methods.
  148. //
  149. // +lockTransaction/+unlockTransaction
  150. //    Frames all uses of the network for WAIS search and retrieval 
  151. //    transactions.  (Typically on port 210.)
  152. //
  153. // +lockFileIO/+unlockFileIO
  154. //    Frames all reading and writing of files, stderr messages, and so on.
  155. //
  156. //
  157. // The other thing that enabling thread support does is to set up a callback
  158. // method which lets you send object messages back to the main thread for
  159. // execution.  This done with MACH messaging.  If thread support is not enabled
  160. // the callback just directly performs the object message.
  161. //
  162. // +callback:anObject perform:(SEL)aSelector with:anArgument
  163. //
  164. // If a thread is aborted in the middle of a locked procedure, you may need
  165. // to create new mutexes to prevent blockage:
  166. //
  167. // +waisNewLocks
  168. //
  169. #ifdef WAIS_THREAD_SUPPORT
  170. #import <cthreads.h>
  171. #endif
  172.  
  173.  
  174. // System includes.
  175. #import <stdio.h>
  176. #import <ctype.h>
  177. #import <string.h>
  178. #import <sys/types.h>
  179. #import <sys/stat.h>
  180. #define USE_SYS_DIR  
  181. #import <sys/dir.h>
  182. #define dirent direct
  183.  
  184.  
  185. // WAIS library includes.
  186. #import <ui.h>
  187. #import <irfileio.h>
  188. #import <docid.h>
  189. #import <sockets.h>
  190. #define WAIS_PROTOCOL_VERSION    "2"    /* integer-valued string */
  191.  
  192.  
  193. // Constants.
  194. // Note: alter these constants with care.  Some values seem tied to WAIS lib.
  195. #define STRINGSIZE        256
  196. #define MAX_MESSAGE_LEN        16384
  197. #define MAX_QUERY_SIZE        1000
  198. #define QUESTION_FILE_VERSION    1
  199. #define CHARS_PER_PAGE        2000
  200. #define SEARCH_LIMIT_DEFAULT    30
  201. #define READ_BUF_SIZE        65535
  202.  
  203.  
  204. // C utility functions defined in Wais.m.
  205. extern void ErrorMsg(const char *title, const char *format, ...);
  206. extern long ReadLongS(char *buffer, FILE *file);
  207. extern long WriteLongS(char *buffer, FILE *file);
  208. extern long ReadDoubleS(char *buffer, FILE *file);
  209. extern long WriteDoubleS(char *buffer, FILE *file);
  210. extern long ReadListX(FILE *file);
  211. extern void read_subfield(const char *source, char *key,
  212.     char *value, int value_size);
  213. extern void replace_controlM(char *buffer, long *length);
  214. extern any* copy_any(any *thing);
  215.  
  216.  
  217. // Global variables defined in Wais.m and used by WAIS library.
  218. extern FILE *logfile;
  219. extern char *log_file_name;
  220.    
  221.  
  222. //-----------------------------------------------------------------------
  223. //            Decoding structured WAIS files.
  224. //
  225. // WAIS structured files contain a single structure, of the form
  226. //    (:name elements...)
  227. // where elements... is a sequence composed of: (1) fields, of the form
  228. //    :name data
  229. // or (2) substructures, of the form
  230. //    :name (:structname elements...)
  231. // or (3) lists of structures of a single type, of the form
  232. //    :name ( (:structname elements...) (:structname elements...) ...)
  233. // The decoders give the type, W_FIELD, W_STRUCT, or W_LIST, for each element
  234. // name.
  235. // 
  236. // W_FIELDs are read/written as formatted strings by the reader() and writer().
  237. // These are stored in the WAIS object as a table associating field name to 
  238. // field value.  Args of field readers/writers are (annoyingly) arranged thus:
  239. //    1    long Function(FILE *file)
  240. //    2    long Function(char *buffer, FILE *file)
  241. //    3    long Function(char *buffer, FILE *file, int bufsize)
  242. // (Actually the arg patterns are even less consistent in the WAIS library,
  243. // so we have replaced ReadLong, WriteLong, ReadDouble, and WriteDouble.)
  244. // The return values are TRUE, FALSE, or END_OF_STRUCT_OR_LIST.
  245. //
  246. // W_STRUCTs are read/written with a recursive call to the -readWaisStruct::::/
  247. // -writeWaisStruct:::: methods.  This allows subclasses of Wais to intercept 
  248. // these calls or make preparations before calling super to do the actual i/o
  249. // (e.g. creating objects for info to be read into/written from).
  250. //
  251. // W_LISTs are handled similarly, except that the recursive call is repeated 
  252. // until a FALSE or END_OF_STRUCT_OR_LIST return.  Note that the element name 
  253. // of the list is passed as a method parameter so that subclasses can find the 
  254. // right list of objects in which to store the structures of the list (however 
  255. // be aware that this arg may be NULL).
  256. //
  257. // The -readWaisStruct::::/-writeWaisStruct:::: methods should quietly pass 
  258. // over unknown fields and structures if possible, and return TRUE, FALSE, or 
  259. // END_OF_STRUCT_OR_LIST as appropriate.  The +fileStructName method should
  260. // return the structName expected at the beginning of the file for that class,
  261. // and +fileStructDecoder gives the corresponding WaisDecoder.
  262. //
  263.  
  264. typedef struct waisDecoder
  265. {
  266.     const char *name;
  267.     int elementType;
  268.     const char *structName;
  269.     struct waisDecoder *subDecoder;
  270.     long (*reader)();
  271.     int readArgs;
  272.     long (*writer)();
  273.     int writeArgs;
  274.     unsigned int maxBufSize;
  275. }
  276.     _WaisDecoder, *WaisDecoder;
  277.  
  278. #define W_FIELD        0
  279. #define W_STRUCT    1
  280. #define W_LIST        2
  281.  
  282.  
  283. //-----------------------------------------------------------------------
  284. //
  285. //            Abstract superclass for WAIS objects.
  286. //
  287. // See description above.
  288. //
  289.  
  290. // Don't change order of includes here.
  291. #import <objc/Object.h>
  292. #import <objc/HashTable.h>
  293. #import <objc/List.h>
  294. #import <objc/Storage.h>
  295. #import <appkit/appkit.h>
  296.  
  297. @interface Wais : Object
  298. {
  299.     NXAtom key;
  300.     id infoFields;
  301. }
  302.  
  303. // Access by object keys.  "Folder" methods should be subclassed.
  304. + objectForKey:(const char *)aKey;
  305. + objectForCompleteKey:(const char *)aKey;
  306. - (const char *)key;
  307. - setKey:(const char *)aKey;
  308. + waisObjectList;
  309. + folderList;
  310. + setFolderList:aList;
  311. + (const char *)defaultHomeFolder;
  312.  
  313. // Creating and destroying WAIS objects.
  314. + initialize;
  315. - initKey:(const char *)aKey; // uses -setKey:
  316. - free;
  317.  
  318. // Editing info fields.
  319. // Note: key and value strings need not be held constant (they're copied).
  320. - (const char *)valueForStringKey:(const char *)aKey;
  321. - (const char *)insertStringKey:(const char *)aKey value:(const char *)aValue;
  322.  
  323. // Reading/writing WAIS files.
  324. // +loadFolder: returns List of Wais objects of given type, free it after use.
  325. // Subclass "Struct" methods as explained above.
  326. // Subclass +checkFileName: if necessary (default always returns YES).
  327. - readWaisFile;
  328. - writeWaisFile;
  329. + loadFolder:(const char *)folderName;
  330. - (short)readWaisStruct:(const char *)structName
  331.     forElement:(const char *)elementName
  332.     fromFile:(FILE *)file
  333.     withDecoder:(WaisDecoder)theDecoder;
  334. - (short)writeWaisStruct:(const char *)structName
  335.     forElement:(const char *)elementName
  336.     toFile:(FILE *)file
  337.     withDecoder:(WaisDecoder)theDecoder;
  338. + (const char *)fileStructName;
  339. + (WaisDecoder)fileStructDecoder;
  340. + (BOOL)checkFileName:(const char *)fileName;
  341.  
  342. // Routing error messages.  Subclass the +errorTitle method.
  343. + setQuiet:(BOOL)yn;
  344. + (BOOL)isQuiet;
  345. + setStringTable:aTable;
  346. + (const char *)errorTitle;
  347.  
  348. // Support for multiple threads.
  349. + lockTransaction;
  350. + unlockTransaction;
  351. + lockFileIO;
  352. + unlockFileIO;
  353. + callback:anObject perform:(SEL)aSelector with:anArgument;
  354. + (port_t)callbackPort;
  355. + waisNewLocks;
  356.  
  357. @end
  358.  
  359.  
  360. // Basic WAIS objects and file extensions.
  361. // (Keep order of includes here too.)
  362. #define W_S_EXT        ".src"
  363. #define W_D_EXT        ".wais"
  364. #define W_Q_EXT        ".qst"
  365. #import "WaisSource.h"
  366. #import "WaisDocument.h"
  367. #import "WaisQuestion.h"
  368.  
  369.  
  370.  
  371.